#ifndef __RENDERSCRIPTENGINE__
#define __RENDERSCRIPTENGINE__

class asIScriptEngine;
class asIScriptModule;
class BlockRenderers;
class Schematic;
class RendererBase;
class Block;
class PrimitiveRendererBase;

#include "..\Math\Point3.h"
#include <vector>
#include <wx\string.h>
#include "..\Schematics\Block.h"

/// <summary>
/// A structure for defining information about this module.
/// </summary>
struct ModuleInfo
{
public:
	std::string Name, Friendly, Version, Author, Dependencies;

	// only used by program
	std::string Namespace, Errors;
	asIScriptModule *Module;
	bool Enabled;

	ModuleInfo() { }

	/// <summary>
	/// Constructor for module info, which fills in all information that the module can use.
	/// </summary>
	/// <param name="name">The full display name of this module.</param>
	/// <param name="friendlyName">Friendly name of this module. Must be all lowercase letters only. This is used for hard dependency links..</param>
	/// <param name="version">The version of this module, for display/update purposes.</param>
	/// <param name="author">The author of this module.</param>
	/// <param name="dependencies">Hard dependencies of this module.
	/// This is a semi-colon separated list of friendly module names.
	/// You only need to use this if you wish to inherit from a shared class from another module which may or may not be there.
	/// Example: <example>"requiredmodule;alsorequiredmodule"</example></param>
	ModuleInfo(const std::string &name, const std::string &friendlyName, const std::string &version, const std::string &author, const std::string &dependencies) :
		Name(name),
		Friendly(friendlyName),
		Version(version),
		Author(author),
		Dependencies(dependencies),
		Enabled(true)
	{
	}
};

class RenderScriptEngine
{
	asIScriptEngine *engine;
	std::vector<ModuleInfo> _modules;
	asIScriptModule *current;

public:
	BlockRenderers *Renderers;

	RenderScriptEngine(BlockRenderers *renderers);
	~RenderScriptEngine();

	inline asIScriptModule *GetCurrentModule() { return current; }

	inline const std::vector<ModuleInfo> &GetModules() { return _modules; }
	void AddScriptSpace(const wxString &str);
	void BuildScripts(RendererBase *renderer);

	void SetGlobal(const char *str, void *ptr);
	void CompileScripts();
	void Execute(Schematic *schematic, PrimitiveRendererBase *renderer, const Block &block, const Point3i &position, void *func);
	bool ExecuteIsFullBlock(void *func);
	bool ExecuteIsOpaqueBlock(void *func);
	void Release(void *obj);
};

#endif